// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps
`default_nettype none

module conv_32b_to_24b 
#(parameter
    OUT_FIFO_DEPTH = 0
)
(
    input  wire I_sclk,
    input  wire I_new_frame,
    // in fifo
    input  wire [ 15: 0] I_in_fifo_usedw,
    output reg  O_in_fifo_rdreq,
    input  wire [ 31: 0] I_in_fifo_rddata,
    // out fifo
    input  wire [ 15: 0] I_out_fifo_usedw,
    output reg  O_out_fifo_wrreq,
    output reg  [ 23: 0] O_out_fifo_wdata
);

/******************************************************************************
                                <localparams>
******************************************************************************/

/******************************************************************************
                              <internal signals>
******************************************************************************/
reg  [ 1: 0] phase;
reg  in_rddata_valid;
reg  [ 1: 0] out_phase;
reg  [ 31: 0] last_data;

/******************************************************************************
                                <module body>
******************************************************************************/
always @(posedge I_sclk)
    if (I_new_frame)
        phase <= 'd0;
    else if (phase == 'd0)
        begin
        if (((!O_in_fifo_rdreq && I_in_fifo_usedw >= 3) || (O_in_fifo_rdreq && I_in_fifo_usedw >= 4)) && I_out_fifo_usedw < OUT_FIFO_DEPTH - 8)
            phase <= 'd1;
        else
            phase <= 'd0;
        end
    else
        phase <= phase + 1'b1;

always @(posedge I_sclk)
    O_in_fifo_rdreq <= (phase != 'd0);

always @(posedge I_sclk)
    in_rddata_valid <= O_in_fifo_rdreq;

always @(posedge I_sclk)
    last_data <= I_in_fifo_rddata;

always @(posedge I_sclk)
    if (!in_rddata_valid)
        out_phase <= 'd0;
    else
        out_phase <= out_phase + 1'b1;

always @(posedge I_sclk)
    case (out_phase)
        0: O_out_fifo_wdata <= I_in_fifo_rddata[23:0];
        1: O_out_fifo_wdata <= {I_in_fifo_rddata[15:0],last_data[31:24]};
        2: O_out_fifo_wdata <= {I_in_fifo_rddata[7:0],last_data[31:16]};
        3: O_out_fifo_wdata <= last_data[31:8];
    endcase

always @(posedge I_sclk)
    O_out_fifo_wrreq <= (in_rddata_valid | (out_phase == 2'd3));
    
endmodule
`default_nettype wire

